package com.cby.android.base.aidl

import android.app.ActivityManager.TaskDescription
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.IBinder.DeathRecipient
import android.os.RemoteException
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.cby.android.base.ILoginCallback
import com.cby.android.base.IUserAction
import com.cby.android.base.R
import com.cby.android.base.aidl.bean.User

/**
 * @description: ChildProcessActivity
 *
 * @author ChenBaoyang
 * @date 2021/10/22 14:05
 */
class ChildProcessActivity : AppCompatActivity() {

    /**
     * 接口对象
     */
    private var iUserAction: IUserAction? = null

    @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_child_process)
        //为了在多任务的时候，可以显示出当前页面的名字，而不是app的名称
        setTaskDescription(TaskDescription("ChildProcessActivity"))
        doBindService()
    }

    private fun doBindService() {
        val serviceIntent = Intent("com.cby.android.base.aidl.UserService")
        serviceIntent.setPackage(packageName)
        bindService(serviceIntent, connection, BIND_AUTO_CREATE)
        /**
         * 方法二
         * Intent serviceIntent = new Intent("com.cby.android.base.aidl.userService");
         * bindService(createExplicitFromImplicitIntent(ChildProcessActivity.this,serviceIntent),
         * connection, Context.BIND_AUTO_CREATE); */
    }

    private var connection: ServiceConnection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            iUserAction = IUserAction.Stub.asInterface(service) //获取服务对象
            Log.i("ChildProcessActivity", "iUserAction = $iUserAction")
            try {
                iUserAction?.asBinder()?.linkToDeath(deathRecipient, 0)
            } catch (e: RemoteException) {
                Log.i("ChildProcessActivity", "e = ${e.toString()}")
            }
        }

        override fun onServiceDisconnected(name: ComponentName) {
            iUserAction = null
        }
    }

    override fun onDestroy() {
        unbindService(connection)
        super.onDestroy()
    }

    private val deathRecipient: DeathRecipient = object : DeathRecipient {
        override fun binderDied() {
            Log.d(
                "ChildProcessActivity",
                "binder died. ThreadName: \${Thread.currentThread().name}"
            )
            //移除死亡代理
            iUserAction!!.asBinder().unlinkToDeath(this, 0)
            iUserAction = null
            // 这里重新绑定远程Service
            doBindService()
        }
    }

    fun onInitClick(view: View) {
        iUserAction?.init("12383", ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, false)
    }

    fun onLoginClick(view: View) {
        iUserAction?.Login(object : ILoginCallback.Stub() {
            @Throws(RemoteException::class)
            override fun onLoginFinish(user: User?, code: Int, message: String?) {
                Toast.makeText(this@ChildProcessActivity, message, Toast.LENGTH_SHORT).show()
            }
        })
    }

    /**
     * 将传进来的Intent进行setComponent配置
     * @param context
     * @param implicitIntent
     * @return
     */
    fun createExplicitFromImplicitIntent(context: Context, implicitIntent: Intent?): Intent? {
        // Retrieve all services that can match the given intent
        val pm = context.packageManager
        val resolveInfo = pm.queryIntentServices(implicitIntent!!, 0)

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size != 1) {
            return null
        }

        // Get component info and create ComponentName
        val serviceInfo = resolveInfo[0]
        val packageName = serviceInfo.serviceInfo.packageName
        val className = serviceInfo.serviceInfo.name
        val component = ComponentName(packageName, className)

        // Create a new intent. Use the old one for extras and such reuse
        val explicitIntent = Intent(implicitIntent)

        // Set the component to be explicit
        explicitIntent.component = component
        return explicitIntent
    }
}